package com.nx.platform.es.biz.esspider.handler;

import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import com.google.common.collect.Maps;
import com.nx.platform.es.biz.esspider.resource.DBManager;
import com.nx.platform.es.common.utils.YamlParser;
import com.nx.platform.es.system.config.ConfigCenter;
import com.nx.platform.es.biz.esspider.entity.Item;
import org.apache.commons.collections4.CollectionUtils;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author
 * @date 2018/01/26
 */
public class HandlersImpl implements Handlers, Constants {

    private final String configKey;
    private final DBManager dbManager;

    public HandlersImpl(String configKey, DBManager dbManager) {
        this.configKey = configKey;
        this.dbManager = dbManager;
    }

    @Override
    public void check(String code) throws RuntimeException {
        List<Handler> handlers = handlerMap(code);
        if (handlers == null || handlers.isEmpty()) {
            throw new IllegalStateException("handle null or empty, code=" + code);
        }
    }

    @SuppressWarnings("unchecked")
    private List<Handler> handlerMap(String code) {
        return (List<Handler>) ConfigCenter.getConfig(configKey + "." + code, settings -> {
            List<Map<?, ?>> configs = YamlParser.parseToList(settings);
            Preconditions.checkState(!configs.isEmpty(), "handlers empty, code=" + code);
            return configs.stream().map(config -> {
                try {
                    return HandlerFactory.createFilter(dbManager, config);
                } catch (Exception e) {
                    Throwables.throwIfUnchecked(e);
                    throw new RuntimeException(e);
                }
            }).collect(Collectors.toList());
        }).orElse(Collections.emptyList());
    }

    @Override
    public void filter(String code, Map<Long, Item> items) throws Exception {
        List<Handler> handlers = handlerMap(code);
        if (CollectionUtils.isEmpty(handlers)) {
            throw new IllegalStateException("handlers empty or not found, code=" + code);
        }
        for (Handler handler : handlers) {
            Map<Long, Item> effectiveItems = Maps.filterValues(items, item -> item != null &&
                    item.getOpType() != Item.OpType.DISCARD && item.getOpType() != Item.OpType.DELETE);

            handler.handle(effectiveItems);
        }
    }

}
